package cn.csg.ams.collect2.poptopics.dataHandle;


import cn.csg.ams.collect2.poptopics.dao.MkPrPfOutageBlackListDao;
import cn.csg.ams.collect2.poptopics.datahub.TupleRecordDataUtils;
import cn.csg.ams.collect2.poptopics.entity.RecordInfo;
import cn.csg.ams.collect2.poptopics.infrastructure.constant.CommonConstant;
import cn.csg.ams.collect2.poptopics.redisPool.LinkCountPool;
import cn.csg.ams.collect2.poptopics.service.MkMcTermAlarmLogService;
import cn.csg.ams.collect2.poptopics.service.MkPrPfOutageBlackListService;
import cn.csg.ams.collect2.poptopics.infrastructure.utils.DateUtil;
import com.aliyun.datahub.client.model.TupleRecordData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 处理告警数据
 */
@Component
public class AlarmHandle {

    private static Logger logger = LoggerFactory.getLogger(AlarmHandle.class);

    /**
     * 链路计数池
     */
    @Autowired
    private LinkCountPool linkCountPool;

    @Autowired
    private MkMcTermAlarmLogService alarmLogService;

    @Autowired
    private MkPrPfOutageBlackListDao blackListDao;

    @Autowired
    private MkPrPfOutageBlackListService blackListService;


    /**
     * 停复电处理类
     */
    @Autowired
    private OutgaeAndRecover outgaeAndRecover;


    /**
     * 处理告警数据
     *
     * @param data       告警数据
     * @param systemTime 数据进入datahub的时间
     */
    public void handle(TupleRecordData data, long systemTime) {
        // 处理告警开始时间
        long startTime = System.currentTimeMillis();

        // 1.清洗告警数据
        if (!checkData(data)) {
            return;
        }

        logger.info("开始处理告警");

        // 运行电能表标识
        String runTermId = TupleRecordDataUtils.getStringField(data, 1);
        // 运行电能表标识
        String runMeterId = TupleRecordDataUtils.getStringField(data, 2);
        // 告警编码
        String alarmCode = TupleRecordDataUtils.getStringField(data, 4);
        // 告警来源，代码分类：GJLY=|{1终端；2电表；3主站}
        String alarmSourCode = TupleRecordDataUtils.getStringField(data, 11);
        // 终端类型
        String termType = TupleRecordDataUtils.getStringField(data, 16);
        // 地区编码
        String areaCode = TupleRecordDataUtils.getStringField(data, "area_code");
        // 市级管理单位编码
        String orgNoCity = areaCode.substring(0, 4);

        // 告警总数量+1 (总数量需要供电所编号，只能在查询到档案后计数) (查询档案后计数太慢，改用地区编码计数)
        // linkCountPool.incrementNum(LinkCountPool.ALARM_TOTAL_NUM_KEY, orgNoCity);

        // 是否及时
        // String preDateStr = TupleRecordDataUtils.getStringField(data, 22);
        // Date preDate = DateUtil.parse(preDateStr, "yyyyMMddHHmmss");
        // if (preDate != null && startTime - preDate.getTime() <= 30000) {
        //     // 告警及时数量+1
        //     linkCountPool.incrementNum(LinkCountPool.ALARM_TIMELY_NUM_KEY, orgNoCity);
        // }

        // 记录停复电告警日志
        // alarmLogService.saveMkMcTermAlarmLogPre(data);
        // sendDatahub.sendToAlarmEvent(data);

        // 查询运行电能表对应的档案信息
        RecordInfo recordInfo = null;
        if ("05".equals(termType) && "1".equals(alarmSourCode)) {
            recordInfo = alarmLogService.getRecordInfoByTerm(runTermId, areaCode);
            recordInfo.setRunMeterId(runTermId);
            runMeterId = runTermId;
        } else {
            recordInfo = alarmLogService.getRecordInfo(runMeterId, areaCode);
        }

        // 检查档案信息
        if (!checkRecordInfo(recordInfo)) {
            // 档案信息有误，直接返回
            return;
        }


        // 3.记录告警日志 (清洗后的数据)
        alarmLogService.saveMkMcTermAlarmLog(data, startTime, systemTime);
        // 告警清洗数量+1
        // linkCountPool.incrementNum(LinkCountPool.ALARM_CLEAN_NUM_KEY, orgNoCity);

        // 告警停电停电
        recordInfo.setAreaCode(areaCode);
        if (CommonConstant.TD_ALARM_CODE.equals(alarmCode)) {
            // 若在黑名单中，则跳过该条停电告警的研判
            boolean isBlack = blackListDao.checkBlackList(runMeterId);
            if (isBlack) {
                return;
            }

            // 若在调试计划中，则跳过该条停电告警的研判
            // boolean isDebugPlan = blackListService.checkDebugPlan(data, recordInfo);
            // if (isDebugPlan) {
            //     return;
            // }
            outgaeAndRecover.alarmOutage(data, recordInfo, systemTime, startTime);
        }

        // 告警复电复电
        if (CommonConstant.FD_ALARM_CODE.equals(alarmCode)) {
            outgaeAndRecover.alarmRecover(data, recordInfo, startTime);
        }
    }


    /**
     * 清洗数据
     */
    private boolean checkData(TupleRecordData data) {
        // 运行终端标识
        Object runTermId = data.getField(1);
        // 运行电能表标识
        Object runMeterId = data.getField(2);
        // 告警来源，代码分类：GJLY=|{1终端；2电表；3主站}
        Object alarmSourCode = data.getField(11);
        // 告警时间
        Object alarmTime = data.getField(23);
        // 告警编码
        String alarmCode = TupleRecordDataUtils.getStringField(data, 4);

        // 是否为停复电告警
        if (!CommonConstant.TD_ALARM_CODE.equals(alarmCode) && !CommonConstant.FD_ALARM_CODE.equals(alarmCode)) {
            return false;
        }

        // 运行电能表标识、 终端标识 是否为空
        if (runTermId == null || runMeterId == null) {
            return false;
        }

        // 告警来源是否为 终端 或 电表
        if (!"1".equals(alarmSourCode) && !"2".equals(alarmSourCode)) {
            return false;
        }

        // 告警时间是否为空
        if (alarmTime == null) {
            return false;
        }

        Date date = DateUtil.parse(alarmTime.toString(), "yyyyMMddHHmmss");
        if ((System.currentTimeMillis() - date.getTime()) > 604800000 || (date.getTime() - System.currentTimeMillis()) >= 86400000) {
            return false;
        }
        return true;
    }


    /**
     * 检查档案信息
     */
    private boolean checkRecordInfo(RecordInfo recordInfo) {
        // 档案是否为空
        if (recordInfo == null) {
            return false;
        }

        // 所属台区是否为空
        if (recordInfo.getTaNo() == null) {
            return false;
        }
        return true;
    }
}
